package org.ling.xuan.channel;

import org.ling.xuan.context.CheckChannelContext;
import org.ling.xuan.context.CheckPipelineContext;
import org.ling.xuan.handler.CheckExceptionHandler;
import org.ling.xuan.rule.CheckRule;

import java.util.ArrayList;
import java.util.List;

public abstract class CheckChannel<T extends CheckChannelContext, R extends CheckPipelineContext> {

    private final List<CheckRule<T, R>> handlers = new ArrayList<>();

    public abstract <T> CheckChannelContext getContext(R pipeContext);

    public void execute(R pipeContext, T channelContext) {
        for (CheckRule<T, R> checkRule : handlers) {
            try {
                if (checkRule.match(pipeContext, channelContext)) {
                    checkRule.check(pipeContext, channelContext);
                }
            } catch (Exception e) {
                CheckExceptionHandler.handleRule(pipeContext, channelContext, checkRule, e);
            }
        }
    }

    public CheckChannel rule(CheckRule<T, R> rule) {
        handlers.add(rule);
        return this;
    }

    public abstract <R extends CheckPipelineContext> boolean match(R pipeContext, CheckChannelContext channelContext);
}
